package com.winit.deploy.util;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.util.ConfigUtil;
import com.winit.common.util.DateUtil;
import com.winit.common.util.FileUtil;
import com.winit.common.util.JSONFileUtil;
import com.winit.deploy.bean.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by wangjian on 16/8/18.
 * 保存非停机发版状态工具类
 */
public class DeployFileUtil {

    private static final Logger logger = LoggerFactory.getLogger(DeployFileUtil.class);

    private static String RELEASE_STATUS_DIR = ConfigUtil.getValue("rootPath") + "Beetle/release/status/";

    private static String RELEASE_INFO_DIR = ConfigUtil.getValue("rootPath") + "Beetle/release/info/";
    /**
     * 记录任务发布的分支名及版本
     */
    private static String RELEASE_TASK_INFO_DIR = ConfigUtil.getValue("rootPath") + "Beetle/release/task/";

    //保存区域状态
    public static boolean saveAreaStatus(String envName, String areaName, AreaStatus areaStatus) {
        String path = getAreaStatusFilePath(envName, areaName);
        isParentFileExist(path);
        return JSONFileUtil.saveFileJson(path, areaStatus);
    }

    //保存任务状态
    private static boolean saveTaskStatus(String envName, String areaName
            , String taskId, DeployTaskStatus taskStatus, String projectName, String editionNum) {
        String path = getAreaTaskStatusFilePath(envName, areaName, taskId);
        isParentFileExist(path);
        String verison = projectName + "#" + editionNum + "#" + DateUtil.getCurDateStr("yyyy-MM-dd HH:mm:ss");
        taskStatus.setVersion(verison);
        return JSONFileUtil.saveFileJson(path, taskStatus);
    }

    public static boolean saveTaskInfo(String envName, String areaName
            , String taskId, String projectName, String editionNum, String btnType) {
        String path = RELEASE_TASK_INFO_DIR + envName + "/" + areaName + "/" + taskId + "/" + DateUtil.getCurDateStr("yyyyMMddHHmmssSSS") + ".json";
        isParentFileExist(path);
        JSONObject data = new JSONObject();
        data.put("projectName", projectName);
        data.put("editionNum", editionNum);
        data.put("date", DateUtil.getCurDateStr("yyyy-MM-dd HH:mm:ss"));
        data.put("btnType", btnType);
        return JSONFileUtil.saveFileJson(path, data);
    }

    //获取区域状态
    public static AreaStatus getAreaStatus(String envName, String areaName) {
        String path = getAreaStatusFilePath(envName, areaName);
        try {
            isFileExist(path);
        } catch (Exception e) {
            logger.info(e.getMessage());
            return new AreaStatus();
        }
        AreaStatus areaStatus = JSONFileUtil.getFileJsonForBean(path, AreaStatus.class);
        return areaStatus == null ? new AreaStatus() : areaStatus;
    }

    //获取任务状态
    public static DeployTaskStatus getAreaTaskStatus(String envName, String areaName, String taskId) {
        String path = getAreaTaskStatusFilePath(envName, areaName, taskId);
        try {
            isFileExist(path);
        } catch (Exception e) {
            logger.info(e.getMessage());
            DeployTaskStatus taskStatus = new DeployTaskStatus();
            taskStatus.setId(taskId);
            return taskStatus;
        }
        DeployTaskStatus taskStatus = JSONFileUtil.getFileJsonForBean(path, DeployTaskStatus.class);
        if (taskStatus == null) {
            taskStatus = new DeployTaskStatus();
            taskStatus.setId(taskId);
        }

        return taskStatus;
    }

    //获取环境列表
    public static List<String> getDeployEnvList() {
        File file = new File(RELEASE_INFO_DIR);
        List<String> list = new ArrayList<>();
        if (!file.exists()) {
            return list;
        }
        for (File f : file.listFiles()) {
            list.add(f.getName().replace(".json", ""));
        }
        return list;
    }

    public static DeployEnv getDeployEnvInfo(String envName) throws Exception {
        String path = getDeployEnvFilePath(envName);
        isFileExist(path);
        DeployEnv deployEnv = JSONFileUtil.getFileJsonForBean(path, DeployEnv.class);
        return deployEnv == null ? new DeployEnv() : deployEnv;
    }

    //保存环境信息
    public static boolean saveDeployEnvInfo(String envName, DeployEnv deployEnv) {
        String path = getDeployEnvFilePath(envName);
        isParentFileExist(path);
        return JSONFileUtil.saveFileJson(path, deployEnv);
    }

    private static void isFileExist(String path) throws Exception {
        File file = new File(path);
        if (!file.exists()) {
            throw new Exception("文件不存在.path=" + path);
        }
    }

    private static void isParentFileExist(String path) {
        File file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
            logger.info("父文件不存在.path=" + path);
        }
    }

    public synchronized static void saveBackPackagePath(String envName, String areaName, String id, String backUpPath) {
        try {
            DeployEnv deployEnv = getDeployEnvInfo(envName);
            if (deployEnv != null) {
                List<DeployArea> areas = deployEnv.getAreas();
                for (int i = 0; i < areas.size(); i++) {
                    DeployArea area = areas.get(i);
                    if (areaName.equals(area.getName())) {
                        List<DeployTask> tasks = area.getTasks();
                        for (int j = 0; j < tasks.size(); j++) {
                            DeployTask task = tasks.get(j);
                            if (id.equals(task.getId())) {
                                task.setBackUpPath(backUpPath);
                                tasks.remove(j);
                                tasks.add(j, task);
                                break;
                            }
                        }
                        area.setTasks(tasks);
                        areas.remove(i);
                        areas.add(i, area);
                        deployEnv.setAreas(areas);
                        saveDeployEnvInfo(envName, deployEnv);
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //tomcat重启时清空所有状态
    public static void cleanEnvStatus() {
        logger.info("清空非停机发布所有状态");
        boolean flag = FileUtil.deleteFile(RELEASE_STATUS_DIR);
        logger.info("清空非停机发布所有状态.flag=" + flag);
    }

    private static String getDeployEnvFilePath(String envName) {
        return RELEASE_INFO_DIR + envName + ".json";
    }

    private static String getAreaStatusFilePath(String envName, String areaName) {
        return RELEASE_STATUS_DIR + envName + "/" + areaName + "/" + areaName + ".json";
    }

    private static String getAreaTaskStatusFilePath(String envName, String areaName, String taskId) {
        return RELEASE_STATUS_DIR + envName + "/" + areaName + "/" + taskId + ".json";
    }

    //task handel 处理任务状态
    public synchronized static DeployTaskStatus handelAreaTaskStatus(String envName, String areaName, String taskId
            , List<String> taskNodeStatus, String projectName, String editionNum, String stopMsg, String statusMsg) {
        DeployTaskStatus taskStatus = DeployFileUtil.getAreaTaskStatus(envName, areaName, taskId);
        taskStatus.setId(taskId);
        //设置状态
        if (taskNodeStatus != null && taskNodeStatus.size() > 0) {
            List<String> status = taskStatus.getStatus();
            if (status == null) {
                status = new ArrayList<>();
                Collections.addAll(status, new String[7]);
            }
            boolean isWrite = false;
            for (int i = 0; i < taskNodeStatus.size(); i++) {
                String s = taskNodeStatus.get(i);
                logger.info("com.winit.deploy.util.DeployFileUtil.handelAreaTaskStatus status=" + s);
                if (isWrite) {
                    status.set(i, s);
                    continue;
                }
                if (!StringUtils.isEmpty(s)) {
                    isWrite = true;
                    status.set(i, s);
                    continue;
                }
            }
            taskStatus.setStatus(status);
        }
        //设置停止信息
        if (!StringUtils.isEmpty(stopMsg)) {
            taskStatus.setStopMsg(stopMsg);
        }
        //设置状态信息
        if (!StringUtils.isEmpty(statusMsg)) {
            taskStatus.setStatusMsg(statusMsg);
        }

        DeployFileUtil.saveTaskStatus(envName, areaName, taskId, taskStatus, projectName, editionNum);
        return taskStatus;
    }

}
